package Frame;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JTextField;

import Function.FCBlockLibrary;
import VWorldGameStudio.FCBlock;
import VWorldGameStudio.FCMap;
import VWorldGameStudio.FCMapAndMsEntity;
import lombok.Getter;
import lombok.Setter;

public class MapEditJpanel extends JPanel {
	private int showxadd = 0;
	private int showyadd = 0;
	private String selectEventName = "null";
	// 显示中心
	private int showx = 0;
	private int showy = 0;
	// 当前坐标
	private int xs = 0;
	private int ys = 0;
	private int collisionLevel = -1; // 地图的实体碰撞数据记录
	private int pngsize = 0;// 渲染一个格子的尺寸
	private int wnum = 0, hnum = 0;// 区域显示的格子数量
	private int movex = 0, movey = 0;// 格子于中心的偏移量
	private int b3x = 0, b3y = 0;// 右键时的坐标
	private boolean ismove = false;
	private FCMap map;
	private Image backgroundImage;
	private FCBlockLibrary blockLib;
	private JTextField xtext, ytext;
	private boolean issave = true;
	private Image selectthum;
	private String selectname;
	// 鼠标实时坐标
	private int selectx;
	private int selecty;
	private String selectnpcname = "null";// npcid
	private String selecttankname = "null";// tankname
	private String monsterid = "null";// monsterid

	private String setlectMapAnimation = "null";

	private static Map<Integer, String> collisionLevelMap = new HashMap<>(); // 地图的实体碰撞数据记录
	static {
		collisionLevelMap.put(-1, "无");
		collisionLevelMap.put(0, "人车可行");
		collisionLevelMap.put(1, "仅人可行");
		collisionLevelMap.put(2, "人车不可行");

	}

	/**
	 * 
	 * @param x
	 * @param y
	 * @param width    地图宽度
	 * @param height   地图高度
	 * @param blockLib 方块库
	 */
	public MapEditJpanel(int x, int y, int width, int height, FCBlockLibrary blockLib) {
		this.blockLib = blockLib;
		setBounds(x, y, width, height);
		setBorder(BorderFactory.createLineBorder(Color.black));
		pngsize = getHeight() / 15;
		wnum = getWidth() / pngsize;
		hnum = getHeight() / pngsize;
		addMouseMotionListener(new MouseMotionListener() {
			@Override
			public void mouseMoved(MouseEvent e) {
				selectx = e.getX();
				selecty = e.getY();
				int ex = e.getX(), ey = e.getY();
				if (ex < getWidth() / 2)
					ys = showy + showyadd + (int) ((ex - getWidth() / 2 - pngsize / 2 - movex) / pngsize);
				else
					ys = showy + showyadd + (int) ((ex - getWidth() / 2 + pngsize / 2 - movex) / pngsize);
				if (ey < getHeight() / 2)
					xs = showx + showxadd + (int) ((ey - getHeight() / 2 - movey - pngsize / 2) / pngsize);
				else
					xs = showx + showxadd + (int) ((ey - getHeight() / 2 - movey + pngsize / 2) / pngsize);
				if (map != null && xs >= 0 && xs < map.getMapWidth() && ys >= 0 && ys < map.getMapHeight())
					collisionLevel = map.getMapEntityOfCoor(xs, ys);
				else
					collisionLevel = -1;
			}

			@Override
			public void mouseDragged(MouseEvent e) {
				if (ismove) {
					if (showy + showyadd > -1 && showy + showyadd < map.getMapHeight()) {
						movex = (e.getX() - b3x) % pngsize;
						showyadd = -(int) ((e.getX() - b3x) / pngsize);
					} else {
						if (showy + showyadd < 0)
							showyadd = -showy;
						if (showy + showyadd >= map.getMapHeight())
							showyadd = map.getMapHeight() - showy - 1;
					}
					if (showx + showxadd > -1 && showx + showxadd < map.getMapWidth()) {
						movey = (e.getY() - b3y) % pngsize;
						showxadd = -(int) ((e.getY() - b3y) / pngsize);
					} else {
						if (showx + showxadd < 0)
							showxadd = -showx;
						if (showx + showxadd >= map.getMapWidth())
							showxadd = map.getMapWidth() - showx - 1;
					}

				}
			}
		});
		addMouseListener(new MouseListener() {
			private int mx = 0, my = 0;

			@Override
			public void mouseReleased(MouseEvent arg0) {
				if (arg0.getButton() == 3) {
					showx += showxadd;
					showy += showyadd;
					showxadd = 0;
					showyadd = 0;
					ismove = false;
				}
				if (arg0.getButton() == 1) {
					int ex = arg0.getX(), ey = arg0.getY();
					if (ex < getWidth() / 2)
						my = showy + showyadd + (int) ((ex - getWidth() / 2 - pngsize / 2 - movex) / pngsize);
					else
						my = showy + showyadd + (int) ((ex - getWidth() / 2 + pngsize / 2 - movex) / pngsize);
					if (ey < getHeight() / 2)
						mx = showx + showxadd + (int) ((ey - getHeight() / 2 - movey - pngsize / 2) / pngsize);
					else
						mx = showx + showxadd + (int) ((ey - getHeight() / 2 - movey + pngsize / 2) / pngsize);
					System.out.println(xs + "," + ys + "=" + mx + "," + my);
					if (map != null) {
						for (int i = xs; i <= mx; i++)
							for (int j = ys; j <= my; j++)
								if (i > -1 && i < map.getMapWidth() && j > -1 && j < map.getMapHeight()) {
									if (selectname != null && !selectname.equals(""))
										map = map.setMapBlockOfCoor(i, j, blockLib.getBlockOfID(selectname));
									if (selectEventName != null) {
										map = map.setMapEventOfCoor(i, j, selectEventName);
										if (selectEventName.equals("null"))
											map = map.setMapEventOfCoor(i, j, "v");
									}
									if (selectnpcname != null) {
										map = map.setMapNpcOfCoor(selectnpcname, i + "*" + j);
										if (selectnpcname.equals("null"))
											map = map.deleteMapNpcOfCoor(i + "*" + j);
									}
									if (selecttankname != null) {
										map = map.setMapTankOfCoor(selecttankname, i + "*" + j);
										if (selecttankname.equals("null"))
											map = map.deleteMapTankOfCoor(i + "*" + j);
									}
//									if (monsterid != null)
//										if (monsterid.equals("null"))
//											map = map.setMapMonsterIDOfCoor(i, j, false, monsterid);
//										else
//											map = map.setMapMonsterIDOfCoor(i, j, true, monsterid);

									if (setlectMapAnimation != null) {
										if (setlectMapAnimation.equals("null"))
											map = map.deleteMapAnimationOfCoor(i + "*" + j);
										else
										  map = map.setMapAnimationOfCoor(setlectMapAnimation, i + "*" + j);
									}
									issave = false;
								}
					}
				}
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
				if (arg0.getButton() == 3) {
					ismove = true;
					b3x = arg0.getX();
					b3y = arg0.getY();
				}
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
			}

			@Override
			public void mouseClicked(MouseEvent e) {

			}
		});

		Timer timer = new Timer();
		timer.schedule(new updataUI(), new Date(), 50);
	}

	@Override
	protected void paintComponent(Graphics g) {
		// 画背景板
		g.setColor(Color.white);
		g.fillRect(0, 0, getWidth(), getHeight());
		// 画格子
		if (map != null) {
			g.setColor(Color.pink);
			for (int i = 0; i < wnum / 2 + 1; i++) {
				int rl = (getWidth() + pngsize) / 2 + pngsize * i + movex;// 右边竖线
				g.drawLine(rl, 0, rl, getHeight());// 右边竖线
				int ll = (getWidth() - pngsize) / 2 - pngsize * i + movex;// 左边竖线
				g.drawLine(ll, 0, ll, getHeight());// 左边竖线
			}
			for (int i = 0; i < hnum / 2 + 1; i++) {
				int ul = (getHeight() - pngsize) / 2 - pngsize * i + movey;// 上面横线
				g.drawLine(0, ul, getWidth(), ul);
				int dl = (getHeight() + pngsize) / 2 + pngsize * i + movey;// 下边横线
				g.drawLine(0, dl, getWidth(), dl);
			}
			g.setColor(new Color(200, 200, 200));
			// 渲染unplace和place
			for (int i = -1; i < hnum + 1; i++) {
				for (int j = -2; j < wnum + 2; j++) {
					int x = showx + showxadd - 7 + i, y = showy + showyadd + j - 11;
					if (x > -1 && x < map.getMapWidth() && y > -1 && y < map.getMapHeight()) {
						String unplacename = map.getUnplaceNameOfCoor(x, y);
						if (!unplacename.equals("v")) {
							Image[][] bl = blockLib.getBlockOfID(unplacename).getBlockImage();
							for (int ii = bl.length - 1; ii > -1; ii--)
								for (int jj = 0; jj < bl[ii].length; jj++)
									if (bl[ii][jj] != null)
										g.drawImage(bl[ii][jj], (j + jj) * pngsize + movex+ (int)(pngsize*0.15),
												(i - bl.length + 1 + ii) * pngsize + 3 + movey, pngsize, pngsize, this);
									else
										g.drawImage(backgroundImage, (j + jj) * pngsize + movex+ (int)(pngsize*0.15),
												(i - bl.length + 1 + ii) * pngsize + 3 + movey, pngsize, pngsize, this);
						}
					} else
						g.drawImage(backgroundImage, (j) * pngsize + movex+ (int)(pngsize*0.15),
								i * pngsize + movey + 3, pngsize, pngsize, this);
				}
				for (int j = -2; j < wnum + 2; j++) {
					int x = showx + showxadd - 7 + i, y = showy + showyadd + j - 11;
					if (x > -1 && x < map.getMapWidth() && y > -1 && y < map.getMapHeight()) {
						String placename = map.getPlaceNameOfCoor(x, y);
						if (!placename.equals("v")) {
							Image[][] bl = blockLib.getBlockOfID(placename).getBlockImage();
							for (int ii = bl.length - 1; ii > -1; ii--)
								for (int jj = 0; jj < bl[ii].length; jj++)
									if (bl[ii][jj] != null)
										g.drawImage(bl[ii][jj], (j + jj) * pngsize + movex+ (int)(pngsize*0.15),
												(i - bl.length + 1 + ii) * pngsize + 3 + movey, pngsize, pngsize, this);
									else
										g.drawImage(backgroundImage, (j + jj) * pngsize + movex+ (int)(pngsize*0.15),
												(i - bl.length + 1 + ii) * pngsize + 3 + movey, pngsize, pngsize, this);
						}
					}
				}
			}

		}
		// 绘制鼠标上的缩略图
		if (selectthum != null) {
			g.drawImage(selectthum, selectx, selecty - 48, this);
		}
		g.setColor(new Color(200,200,200));
		g.setFont(new Font("黑体", Font.BOLD, 20));

		int line1 = selecty + 20;
		int line2 = selecty + 40;
		int line3 = selecty + 60;
		int line4 = selecty + 80;
		int line5 = selecty + 100;
		int line6 = selecty + 120;
		int line7 = selecty + 140;
		int line8 = selecty + 160;
		// x轴修正值（同△x）
		int δx = -5;

		String mmmmm = "(x:" + xs + ", y:" + ys + ")";
		// selectx - mmmmm.length() * 7
		g.drawString("【当前坐标】" + mmmmm, selectx - δx, line1);
		g.drawString("【碰撞等級】" + collisionLevelMap.get(collisionLevel), selectx - δx, line2);
		String nnnnn = ((map != null) ? map.getEventNameOfCoor(xs, ys) : "null") + ","
				+ ((map != null) ? map.getMapNpcNameOfCoor(xs + "*" + ys) : "null");
		g.drawString("【事件名】" + nnnnn, selectx - δx, line3);
		String tankname = ((map != null) ? map.getMapTankNameOfCoor(xs + "*" + ys) : "") + ":" + selecttankname;
		g.drawString("【战车名称】" + tankname, selectx - δx, line4);
		g.drawString("【？：NPC名】" + selectEventName + "," + selectnpcname, selectx - δx, line5);
		g.drawString("【?：怪物名称】" + ((map != null) ? map.getMapMonsterIDOfCoor(xs, ys) : "null"), selectx - δx, line6);
		g.drawString("【怪物ID】" + ((monsterid != null) ? monsterid : "null"), selectx - δx, line7);
		String curMapAni = ((map != null) ? map.getMapAnimationOfCoor(xs + "*" + ys) : "null");
		g.drawString("【地图动画】" +curMapAni+":"+((setlectMapAnimation != null) ? setlectMapAnimation : "null"), selectx - δx, line8);
		δx=-4;
		g.setColor(Color.white);
		g.drawString("【当前坐标】" + mmmmm, selectx - δx, line1-1);
		g.drawString("【碰撞等級】" + collisionLevelMap.get(collisionLevel), selectx - δx, line2-1);
		g.drawString("【事件名】" + nnnnn, selectx - δx, line3-1);
		g.drawString("【战车名称】" + tankname, selectx - δx, line4-1);
		g.drawString("【？：NPC名】" + selectEventName + "," + selectnpcname, selectx - δx, line5-1);
		g.drawString("【?：怪物名称】" + ((map != null) ? map.getMapMonsterIDOfCoor(xs, ys) : "null"), selectx - δx, line6-1);
		g.drawString("【怪物ID】" + ((monsterid != null) ? monsterid : "null"), selectx - δx, line7-1);
		g.drawString("【地图动画】" +curMapAni+":"+((setlectMapAnimation != null) ? setlectMapAnimation : "null"), selectx - δx, line8-1);

		// 绘制画板中心
		g.setColor(Color.black);
		g.drawLine(getWidth() / 2 - 9, getHeight() / 2, getWidth() / 2 + 10, getHeight() / 2);
		g.drawLine(getWidth() / 2, getHeight() / 2 - 9, getWidth() / 2, getHeight() / 2 + 10);
	}

	// 设置渲染出来的新地图数据
	public void setNewMap(FCMap map) {
		this.map = map;
		this.backgroundImage = Toolkit.getDefaultToolkit()
				.getImage((map.getBackgroundURL() == null) ? "./image/ChunSe1.png" : map.getBackgroundURL());
		issave = true;
		showx = map.getMapWidth() / 2;
		showy = map.getMapHeight() / 2;
	}

	// 设置中心坐标现实
	public void setJTextFieldOfXY(JTextField xtext, JTextField ytext) {
		this.xtext = xtext;
		this.ytext = ytext;
	}

	// 获取地图
	public FCMap getNewMap() {
		return map;
	}

	// 设置地图保存
	public void setSave() {
		issave = true;
	}

	public void setNotSave() {
		issave = false;
	}

	// 获取该编辑地图是否保存
	public boolean isSave() {
		return issave;
	}

	// 设置缩略图
	public void setBlockThum(Image im, String name) {
		this.selectthum = im;
		this.selectname = name;
	}

	// 设置要添加的事件
	public void setSelectEventName(String name) {
		this.selectEventName = name;
		this.selectthum = null;
		this.selectname = null;
		this.selectnpcname = null;
		this.monsterid = null;
		this.selecttankname = null;
		this.setlectMapAnimation = null;
	}

	// 设置要添加的人物
	public void setSelectNpcName(String name) {
		this.selectnpcname = name;
		this.selectthum = null;
		this.selectname = null;
		this.selectEventName = null;
		this.monsterid = null;
		this.selecttankname = null;
		this.setlectMapAnimation = null;
	}

	// 设置要添加的坦克
	public void setSelectTankName(String name) {
		this.selecttankname = name;
		this.selectthum = null;
		this.selectname = null;
		this.selectEventName = null;
		this.monsterid = null;
		this.selectnpcname = null;
		this.setlectMapAnimation = null;
	}

	// 设置要添加的怪物
	public void setSelectMonsterName(String name) {
		this.monsterid = name;
		this.selectnpcname = null;
		this.selectthum = null;
		this.selectname = null;
		this.selectEventName = null;
		this.selecttankname = null;
		this.setlectMapAnimation = null;
	}

	public void setSelecAnimationName(String name) {
		this.monsterid = null;
		this.selectnpcname = null;
		this.selectthum = null;
		this.selectname = null;
		this.selectEventName = null;
		this.selecttankname = null;
		this.setlectMapAnimation = name;
	}
	private class updataUI extends TimerTask {
		@Override
		public void run() {
			repaint();
		}
	}
}
